package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.commons.constants.CommonConstants;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.CourseAuditDto;
import com.xuecheng.commons.model.dto.CourseBaseDto;
import com.xuecheng.commons.model.dto.CourseDto;
import com.xuecheng.commons.model.dto.PageRequest;
import com.xuecheng.commons.model.vo.CourseBaseVo;
import com.xuecheng.commons.model.vo.PageResponseResult;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.config.MinioProperties;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.mappers.CourseBaseMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.TeachplanService;
import com.xuecheng.web.exceptions.BusinessException;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * 课程基本信息 服务实现类
 */
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    @Autowired
    private TeachplanService teachplanService;

    //分页查询课程
    public PageResponseResult findAll(CourseDto dto, PageRequest request) {
        Integer pageNo = request.getPageNo();
        Integer pageSize = request.getPageSize();
        //1、分页页码参数（Page对象)
        Page<CourseBase> pageParam = new Page<>(pageNo,pageSize); //当前页，每页条数
        //2、查询条件
        LambdaQueryWrapper<CourseBase> qw = new LambdaQueryWrapper<>();
        //2.1 添加查询条件
        String courseName = dto.getCourseName();
        if(!StringUtils.isEmpty(courseName)) {
            qw.like(CourseBase::getName,"%"+courseName+"%");
        }
        String auditStatus = dto.getAuditStatus();
        if(!StringUtils.isEmpty(auditStatus)) {
            qw.eq(CourseBase::getAuditStatus,auditStatus);
        }
        String teachmode = dto.getTeachmode();
        if(!StringUtils.isEmpty(teachmode)) {
            qw.eq(CourseBase::getTeachmode,teachmode);
        }
        //qw.eq(CourseBase::getCompanyId, AuthInfoHolder.getCompanyId());
        //3、分页查询
        Page<CourseBase> page = this.page(pageParam, qw);//
        //4、构造返回
        return new PageResponseResult(page.getTotal(),page.getRecords());
    }

    @Autowired
    private MinioClient client;

    @Autowired
    private MinioProperties properties;

    //上传课程封面图片
    public ResponseResult<String> upload(MultipartFile uploadFile) throws Exception {
        //文件输入流
        InputStream inputStream = uploadFile.getInputStream();
        //文件上传的路径
        String filepath = "/images/"+new SimpleDateFormat("yyyy/MM/dd")
                        .format(new Date())
                    +"/" + UUID.randomUUID().toString() + uploadFile.getOriginalFilename();
        //设置上传对象PutObjectArgs
        PutObjectArgs args = PutObjectArgs.builder()
                .object(filepath)
                .bucket(properties.getBucket())
                .stream(inputStream,inputStream.available(),-1)
                .contentType("image/jpg")
                .build();
        //通过client上传
        client.putObject(args);
        //构造请求地址
        String url = properties.getDomain() +"/"+ properties.getBucket() + filepath;
        //返回
        return ResponseResult.okResult(url);
    }

    //保存课程
    public ResponseResult<CourseBaseVo> saveCourseBase(CourseBaseDto dto) {
        //0、验证dto参数（略）
        //1、构造保存对象CourseBase
        CourseBase courseBase = BeanHelper.copyProperties(dto, CourseBase.class);
        //2、设置必填项属性（企业名称，审核状态，删除状态，时间）
        courseBase.setCompanyName(AuthInfoHolder.getAuthInfo().getCompanyName());
        courseBase.setStatus(CommonConstants.USING_FLAG); //删除状态
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS); //审核状态
        courseBase.setCreateDate(new Date());
        //3、设置章节数（需要后续改造）
        courseBase.setPlanNum(0);
        //4、保存课程
        boolean save = this.save(courseBase);
        if(!save) {
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        //补充：保存一级的课程大纲
        Teachplan tp = new Teachplan();
        tp.setPname(courseBase.getName());
        tp.setParentid(0l);
        tp.setGrade(CourseConstants.FIRST_LEVEL);
        tp.setCourseId(courseBase.getId());
        tp.setStatus(CommonConstants.USING_FLAG);
        tp.setCreateDate(new Date());
        tp.setCompanyId(AuthInfoHolder.getCompanyId());
        teachplanService.save(tp);

        //5、返回
        CourseBaseVo vo = new CourseBaseVo();
        vo.setCourseBaseId(courseBase.getId());

        return ResponseResult.okResult(vo);
    }

    /**
     * 更新课程
     *  针对已发布，已提交，已审核的课程，不能进行更新
     *  dto：包含需要更新的id
     */
    public ResponseResult<CourseBaseVo> updateCourse(CourseBaseDto dto) {
        //1、根据id查询数据库中的课程
        CourseBase base = this.getById(dto.getId());
        //2、判断课程是否存在
        if(base == null) {
            throw new BusinessException(ErrorCode.UPDATEEERROR);
        }
        //3、判断数据库表中的审核状态是否合法
        if(base.getAuditStatus().equals(CourseConstants.AUDIT_COMMIT_STATUS) ||
                base.getAuditStatus().equals(CourseConstants.AUDIT_PASTED_STATUS) ||
                base.getAuditStatus().equals(CourseConstants.AUDIT_PUBLISHED_STATUS) ) {
            throw new BusinessException(ErrorCode.UPDATEEERROR);
        }
        //4、更新课程信息
        CourseBase courseBase = BeanHelper.copyProperties(dto, CourseBase.class);
        boolean update = this.updateById(courseBase); //成功-true
        if(!update) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        //5、返回
        CourseBaseVo vo = new CourseBaseVo();
        vo.setCourseBaseId(dto.getId());
        return ResponseResult.okResult(vo);
    }

    /**
     * 课程提交：修改状态
     */
    public ResponseResult commit(Long courseBaseId) {
        //1、根据id查询
        CourseBase base = this.getById(courseBaseId);
        //2、判断状态是否可以提交
        if(!base.getAuditStatus().equals(CourseConstants.AUDIT_UNPAST_STATUS) &&
                !base.getAuditStatus().equals(CourseConstants.AUDIT_DISPAST_STATUS) ) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        //3、更新状态
        base.setAuditStatus(CourseConstants.AUDIT_COMMIT_STATUS);
        boolean update = this.updateById(base);
        if(!update) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        return ResponseResult.okResult();
    }

    //运营平台审核课程
    public ResponseResult approve(CourseAuditDto dto) {
        //1、根据id查询
        CourseBase base = this.getById(dto.getCourseBaseId());
        //2、判断状态是否可以审核，已提交-->审核
        if(!base.getAuditStatus().equals(CourseConstants.AUDIT_COMMIT_STATUS)) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        //3、更新状态和意见
        base.setAuditStatus(dto.getAuditStatus());
        base.setAuditMind(dto.getAuditMind());
        boolean update = this.updateById(base);
        if(!update) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        return ResponseResult.okResult();
    }
}
